//============================================================================
// Name        : Lexon.cpp
// Author      : lucmir@dcc.ufmg.br
// Description :
//============================================================================

#include "Lexon.h"


Lexon::Lexon() {
	this->len = 0;
}

Lexon::~Lexon() {
	std::map<unsigned int, Lexon::VocabularyItem *>::iterator itr;
	for(itr=this->vocabulary.begin(); itr!=this->vocabulary.end(); itr++) {
		delete itr->second;
	}
	this->vocabulary.clear();
	this->termIdMap.clear();
}


unsigned int Lexon::contains(std::string term) {
	std::map<std::string, unsigned int>::iterator itr;

	itr = this->termIdMap.find(term);
	if ( itr == this->termIdMap.end() ) {
		return NOT_IN_VOCABULARY;
	}
	return itr->second;
}

unsigned int Lexon::insert(std::string term) {
	this->termIdMap[term] = ++this->len;
	return this->len;
}

void Lexon::insert(std::string term, unsigned int termId) {
	this->termIdMap[term] = termId;
	this->len++;
}

unsigned int Lexon::getLen() {
	return this->len;
}

unsigned int Lexon::getVocabularyLen() {
	return this->vocabulary.size();
}

unsigned int Lexon::getTermId(std::string term) {
	return this->termIdMap[term];
}

void Lexon::setTermId(std::string term, unsigned int termId) {
	this->termIdMap[term] = termId;
}

void Lexon::vocabularyInsert(unsigned int termId, unsigned int tf, unsigned int pos) {
	this->vocabulary[termId] = new Lexon::VocabularyItem(tf, pos);
}

void Lexon::vocabularyInsert(unsigned int termId) {
	this->vocabulary[termId] = new Lexon::VocabularyItem(0, 0);
}

Lexon::VocabularyItem *Lexon::vocabularyGetItem(unsigned int termId) {
	std::map<unsigned int, Lexon::VocabularyItem *>::iterator itr;
	itr = this->vocabulary.find(termId);
	if(itr != this->vocabulary.end()) {
		return itr->second;
	}
	return NULL;
}

Lexon::VocabularyItem *Lexon::vocabularyGetItem(std::string term) {
	unsigned int termId = this->getTermId(term);
	if(termId) {
		return this->vocabularyGetItem(termId);
	}
	return NULL;
}

void Lexon::setPosition(unsigned int termId, unsigned int pos) {
	Lexon::VocabularyItem *item = this->vocabularyGetItem(termId);
	if(item != NULL) {
		item->setPosition(pos);
	}
}

void Lexon::incTf(unsigned int termId) {
	unsigned int tf;
	Lexon::VocabularyItem *item = this->vocabularyGetItem(termId);
	if (item != NULL) {
		tf = item->getTf();
		item->setTf(tf+1);
	}
}

unsigned int Lexon::getTermTf(unsigned int termId) {
	Lexon::VocabularyItem *item = this->vocabularyGetItem(termId);
	if(item != NULL) {
		return item->getTf();
	}
	return 0;
}

bool Lexon::printToFile(std::string vocabularyFileName) {
	std::ofstream file;
	std::map<std::string, unsigned int>::iterator itr;
	std::string term;
	unsigned int termId, tf, pos;

	// Vocabulary file
	file.open(vocabularyFileName.c_str());
	if(!file.is_open()) {
		std::cout << "\nERRO: Não foi possível abrir o arquivo: " << vocabularyFileName << "\n";
		return false;
	}
	for(itr=this->termIdMap.begin(); itr!=this->termIdMap.end(); itr++) {
		term = itr->first;
		termId = itr->second;
		tf = this->vocabulary[termId]->getTf();
		pos = this->vocabulary[termId]->getPosition();
		file << term << ' ' << termId << ' ' << tf << ' ' << pos << '\n';
	}
	file.close();

	return true;
}

bool Lexon::readFromFile(std::string vocabularyFileName) {
	std::ifstream file;
	std::string line;
	std::string term;
	unsigned int termId, tf, pos;

	// Vocabulary file
	file.open(vocabularyFileName.c_str());
	if(!file.is_open()) {
		std::cout << "\nERRO: Não foi possível abrir o arquivo: \"" << vocabularyFileName << "\"\n\n";
		return false;
	}
	while(!file.eof()) {
		getline(file, line);
		std::istringstream istr(line);
		istr >> term;
		istr >> termId;
		istr >> tf;
		istr >> pos;
		this->insert(term, termId);
		this->vocabularyInsert(termId, tf, pos);
	}
	file.close();

	return true;
}
